use std::fs;
use std::fs::File;
use std::path::PathBuf;
use std::sync::Arc;
use log::error;
use std::sync::Mutex;
use once_cell::sync::Lazy;
use crate::model::Config;

// 可变全局变量excel_path
static EXCEL_PATH: Lazy<Arc<Mutex<String>>> = Lazy::new(|| {
    Arc::new(Mutex::new(String::new()))
});

pub fn get_excel_path_mem() -> String {
    let binding = EXCEL_PATH.clone();
    let mutex_guard = binding.lock().unwrap();
    mutex_guard.clone()
}

pub fn set_excel_path_mem(excel_path:String) {
    let binding = EXCEL_PATH.clone();
    let mut mutex_guard = binding.lock().unwrap();
    *mutex_guard = excel_path;
}

pub fn get_config_dir() -> Option<PathBuf> {
    let home_dir = dirs::home_dir().unwrap();
    let config_path = home_dir.join(".des-tool");
    if !config_path.exists() {
        let create = File::create(&config_path);
        if let Err(err) = create {
            error!("create config error: {:?}",err);
            return None;
        }
        let write = fs::write(&config_path, "{}");
        if let Err(err) = write {
            error!("write config error: {:?}",err);
            return None;
        }
    }
    return Some(config_path);
}

pub fn get_config() -> Option<Config> {
    let config_path_option = get_config_dir();
    match config_path_option {
        None => None,
        Some(config_path) => {
            let json = fs::read_to_string(config_path).unwrap();
            let result = serde_json::from_str::<Config>(json.as_str());
            match result {
                Ok(config) => {
                    Some(config)
                }
                Err(err) => {
                    error!("get config error: {:?}",err);
                    None
                }
            }
        }
    }
}


pub fn set_config(update_config: Config) -> Option<Config> {
    let config_option = get_config();
    match config_option {
        None => None,
        Some(mut config) => {
            let save_path_option = update_config.save_path;
            if let Some(save_path) = save_path_option {
                config.save_path = Some(save_path);
            }
            let excel_path_option = update_config.excel_path;
            if let Some(excel_path) = excel_path_option {
                config.excel_path = Some(excel_path);
            }
            save_config(config)
        }
    }
}

pub fn save_config(config: Config) -> Option<Config> {
    let config_path_option = get_config_dir();
    match config_path_option {
        None => None,
        Some(config_path) => {
            let json_result = serde_json::to_string(&config);
            match json_result {
                Ok(json) => {
                    let write = fs::write(config_path, json);
                    if let Err(err) = write {
                        error!("set config error: {:?}",err);
                        return None;
                    }
                    Some(config.clone())
                }
                Err(err) => {
                    error!("set config error: {:?}",err);
                    None
                }
            }
        }
    }
}

pub fn set_save_path(save_path_str: String) -> Option<Config> {
    set_config(Config {
        excel_path: None,
        save_path: Some(save_path_str),
    })
}

pub fn set_excel_path(excel_path_str: String) -> Option<Config> {
    set_config(Config {
        excel_path: Some(excel_path_str),
        save_path: None,
    })
}
